<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Relation Knowledge</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
	tex: {
		inlineMath: '$', '$'], ['\\(', '\\)'
	},
	svg: {
		fontCache: 'global'
	}
};
</script>
<script type="text/javascript" id="MathJax-script" async
	src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Relation Knowledge' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">assertions</a></li><li><a href="index.html#4">Chapter 4: Assertions</a></li><li><b>Relation Knowledge</b></li></ul></div>
<p class="purpose">This section draws inferences about the relationships between objects or values.</p>

<ul class="toc"><li><a href="4-rk.html#SP1">&#167;1. Relationship nodes</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Relationship nodes.</b>Here we have a relationship between subtrees \(T_X\) and \(T_Y\), where \(T_X\)
must be a list of values or objects (joined into an <span class="extract"><span class="extract-syntax">AND_NT</span></span> tree), and
\(T_Y\) must be a <span class="extract"><span class="extract-syntax">RELATIONSHIP_NT</span></span> subtree &mdash; which is usually a node
annotated with the predicate meant, and beneath that another list of
objects or values, but there are two exceptional cases to take care of.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Relational::assert_subtree_in_relationship</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Assertions::Relational::assert_subtree_in_relationship</span></span>:<br/>Assertions - <a href="4-ass.html#SP6_3_34_4">&#167;6.3.34.4</a>, <a href="4-ass.html#SP6_3_36">&#167;6.3.36</a>, <a href="4-ass.html#SP6_3_37">&#167;6.3.37</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">value</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"assert relation between null subtrees"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">) != </span><span class="identifier-syntax">RELATIONSHIP_NT</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"asserted malformed relationship subtree"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">) == </span><span class="identifier-syntax">AND_NT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="4-rk.html#SP1" class="function-link"><span class="function-syntax">Assertions::Relational::assert_subtree_in_relationship</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="4-rk.html#SP1" class="function-link"><span class="function-syntax">Assertions::Relational::assert_subtree_in_relationship</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">, </span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">IF_MODULE</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">MapRelations::get_mapping_relationship</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="4-rk.html#SP1_3" class="named-paragraph-link"><span class="named-paragraph">Exceptional relationship nodes for map connections</span><span class="named-paragraph-number">1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pronoun_usage</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pro</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_pronoun</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pro</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pro</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">pronoun_used</span><span class="plain-syntax"> == </span><span class="identifier-syntax">here_pronoun</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="4-rk.html#SP1_2" class="named-paragraph-link"><span class="named-paragraph">Exceptional relationship nodes for placing objects "here"</span><span class="named-paragraph-number">1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-rk.html#SP1_1" class="named-paragraph-link"><span class="named-paragraph">Standard relationship nodes (the vast majority)</span><span class="named-paragraph-number">1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1" class="paragraph-anchor"></a><b>&#167;1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Standard relationship nodes (the vast majority)</span><span class="named-paragraph-number">1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">binary_predicate</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BinaryPredicates::get_reversal</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_relationship</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"asserted bp-less relationship subtree"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SettingPropertyRelations::fix_property_bp</span><span class="plain-syntax">(</span><span class="identifier-syntax">bp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="4-rk.html#SP3" class="function-link"><span class="function-syntax">Assertions::Relational::assert_relation_between_subtrees</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">bp</span><span class="plain-syntax">, </span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-rk.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_2" class="paragraph-anchor"></a><b>&#167;1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Exceptional relationship nodes for placing objects "here"</span><span class="named-paragraph-number">1.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_HereFailedOnNothing</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"that is an assertion which puts nothing 'here'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"which looks as if it might be trying to give me negative rather "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"than positive information. There's no need to tell me something "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"like 'Here is nothing.': just don't put anything there."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Assert::true_about</span><span class="plain-syntax">(</span>
<span class="plain-syntax">            </span><a href="8-cu.html#SP6" class="function-link"><span class="function-syntax">Propositions::Abstract::to_put_here</span></a><span class="plain-syntax">(),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">), </span><span class="identifier-syntax">prevailing_mood</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-rk.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_3" class="paragraph-anchor"></a><b>&#167;1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Exceptional relationship nodes for map connections</span><span class="named-paragraph-number">1.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-rk.html#SP1_3_1" class="named-paragraph-link"><span class="named-paragraph">Make some paranoid checks that the map subtree is valid</span><span class="named-paragraph-number">1.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><a href="4-rk.html#SP2" class="function-link"><span class="function-syntax">Assertions::Relational::substitute_at_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="4-rk.html#SP2" class="function-link"><span class="function-syntax">Assertions::Relational::substitute_at_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">iy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">iy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::is_nothing_object_constant</span><span class="plain-syntax">(</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Node::get_evaluation</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MapFromNowhere</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="string-syntax">"the source of a map connection can't be nowhere"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"so sentences like 'The pink door is south of nowhere.' are not "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"allowed."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MapFromNonroom2</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="string-syntax">"the source of a map connection has to be a room or door"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"so sentences like 'The pink door is south of 0.' are not "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"allowed."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">iy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">id</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"malformed directional subtree"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::is_nothing_object_constant</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Map::connect</span><span class="plain-syntax">(</span><span class="identifier-syntax">iy</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_evaluation</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Map::connect</span><span class="plain-syntax">(</span><span class="identifier-syntax">iy</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">), </span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Val is $P\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MapToNonobject</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"the destination of a map connection has to be either a room, "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"a door or 'nowhere'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"but here the destination doesn't even seem to be an object."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-rk.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_3_1" class="paragraph-anchor"></a><b>&#167;1.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make some paranoid checks that the map subtree is valid</span><span class="named-paragraph-number">1.3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"malformed DIRECTION"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) != </span><span class="identifier-syntax">PROPER_NOUN_NT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"this is not straightforward in saying which room (or door) leads away from"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"and should just name the source."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">relationship_subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) != </span><span class="identifier-syntax">PROPER_NOUN_NT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"this is not straightforward in saying which direction the room (or door) lies in"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"and should just name the direction."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-rk.html#SP1_3">&#167;1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Relational::substitute_at_node</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Assertions::Relational::substitute_at_node</span></span>:<br/><a href="4-rk.html#SP1_3">&#167;1.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_evaluation</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NonlocalVariables::substitute_constants</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="4-rpt.html#SP1" class="function-link"><span class="function-syntax">Refiner::give_spec_to_noun</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>So the majority case above calls <span class="extract"><span class="extract-syntax">Assertions::Relational::assert_relation_between_subtrees</span></span> to say
that subtrees \(T_X\) and \(T_Y\), where \(T_X\) is a single value or object and
\(T_Y\) is a list of values or objects (joined into an <span class="extract"><span class="extract-syntax">AND_NT</span></span> tree).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Relational::assert_relation_between_subtrees</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Assertions::Relational::assert_relation_between_subtrees</span></span>:<br/><a href="4-rk.html#SP1_1">&#167;1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">px</span><span class="plain-syntax">, </span><span class="identifier-syntax">binary_predicate</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bp</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">py</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">) == </span><span class="identifier-syntax">AND_NT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="4-rk.html#SP3" class="function-link"><span class="function-syntax">Assertions::Relational::assert_relation_between_subtrees</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">, </span><span class="identifier-syntax">bp</span><span class="plain-syntax">, </span><span class="identifier-syntax">py</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="4-rk.html#SP3" class="function-link"><span class="function-syntax">Assertions::Relational::assert_relation_between_subtrees</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">, </span><span class="identifier-syntax">bp</span><span class="plain-syntax">, </span><span class="identifier-syntax">py</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">) == </span><span class="identifier-syntax">WITH_NT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="4-rk.html#SP3" class="function-link"><span class="function-syntax">Assertions::Relational::assert_relation_between_subtrees</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">, </span><span class="identifier-syntax">bp</span><span class="plain-syntax">, </span><span class="identifier-syntax">py</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">) == </span><span class="identifier-syntax">EVERY_NT</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-rk.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Issue problem for "every" used on the right</span><span class="named-paragraph-number">3.3</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> reverse the relation (and swap the terms) to ensure it's the right way round</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">BinaryPredicates::is_the_wrong_way_round</span><span class="plain-syntax">(</span><span class="identifier-syntax">bp</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pz</span><span class="plain-syntax"> = </span><span class="identifier-syntax">px</span><span class="plain-syntax">; </span><span class="identifier-syntax">px</span><span class="plain-syntax"> = </span><span class="identifier-syntax">py</span><span class="plain-syntax">; </span><span class="identifier-syntax">py</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pz</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">bp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BinaryPredicates::get_reversal</span><span class="plain-syntax">(</span><span class="identifier-syntax">bp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-rk.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Normalise the two noun leaves</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-rk.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Impose a tedious restriction on relations between objects and values</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">Assert::true</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><a href="8-cu.html#SP4" class="function-link"><span class="function-syntax">Propositions::Abstract::to_set_relation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">bp</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">), </span><span class="identifier-syntax">Node::get_evaluation</span><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">), </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">), </span><span class="identifier-syntax">Node::get_evaluation</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">)),</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">prevailing_mood</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. </b>Both sides have to be nouns representing constant values:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Normalise the two noun leaves</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="4-rpt.html#SP6" class="function-link"><span class="function-syntax">Refiner::nominalise_adjective</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">); </span><a href="4-rpt.html#SP4" class="function-link"><span class="function-syntax">Refiner::turn_player_to_yourself</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="4-rpt.html#SP6" class="function-link"><span class="function-syntax">Refiner::nominalise_adjective</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">); </span><a href="4-rpt.html#SP4" class="function-link"><span class="function-syntax">Refiner::turn_player_to_yourself</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">) != </span><span class="identifier-syntax">PROPER_NOUN_NT</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">) != </span><span class="identifier-syntax">COMMON_NOUN_NT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">) != </span><span class="identifier-syntax">PROPER_NOUN_NT</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">) != </span><span class="identifier-syntax">COMMON_NOUN_NT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BadRelation</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"this description of a relationship makes no sense to me"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"and should be something like 'X is in Y' (or 'on' or 'part of Y'); "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"or else 'X is here' or 'X is east of Y'."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-rk.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>&#167;3.2. </b>At some point we should probably revisit this.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Impose a tedious restriction on relations between objects and values</span><span class="named-paragraph-number">3.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="8-er.html#SP4" class="function-link"><span class="function-syntax">ExplicitRelations::relates_values_not_objects</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">bp</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">        (((</span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">KindSubjects::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">)))) ||</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">KindSubjects::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">)))))) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_KindRelatedToValue</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"relations between objects and values have to be made one "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"object at a time"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"not using kinds of object to make multiple relationships in "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"a single sentence. (Sorry for this restriction. It's sometimes "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"possible to get around it using words like 'every': for example, "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"'Every person is in the Ballroom.' is allowed.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-rk.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3" class="paragraph-anchor"></a><b>&#167;3.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for "every" used on the right</span><span class="named-paragraph-number">3.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EveryWrongSide</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="string-syntax">"'every' can only be used on the other side of the verb"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"because of limitations in Inform (but also to avoid certain possible "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"ambiguities). In general, 'every' should be applied to the subject of an "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"assertion sentence and not the object. Thus 'Sir Francis prefers every "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"blonde' is not allowed, but 'Every blonde is preferred by Sir Francis' is. "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"(It would be different if, instead of Sir Francis who's just one man, "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"the name of a kind appeared: 'A vehicle is in every room' is fine, for "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"example, because 'vehicle' is a kind.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-rk.html#SP3">&#167;3</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="4-pk.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresschapter"><a href="2-bv.html">2</a></li><li class="progresschapter"><a href="3-dlr.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-nr.html">nr</a></li><li class="progresssection"><a href="4-rpt.html">rpt</a></li><li class="progresssection"><a href="4-tc.html">tc</a></li><li class="progresssection"><a href="4-ass.html">ass</a></li><li class="progresssection"><a href="4-npa.html">npa</a></li><li class="progresssection"><a href="4-pk.html">pk</a></li><li class="progresscurrent">rk</li><li class="progresssection"><a href="4-ass2.html">ass2</a></li><li class="progresssection"><a href="4-imp.html">imp</a></li><li class="progresschapter"><a href="5-id.html">5</a></li><li class="progresschapter"><a href="6-rls.html">6</a></li><li class="progresschapter"><a href="7-tc.html">7</a></li><li class="progresschapter"><a href="8-kpr.html">8</a></li><li class="progressnext"><a href="4-ass2.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

